﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Services.Discovery;
using System.IO;
using System.Xml;

namespace WSInspection
{
    /// <summary>
    /// This class provides functionality to create a WSIL file (Web Service Inspection Language)
    /// You can Add WebService to WSIL or even Remove WebService from WSIL.
    /// </summary>
    /// <example>
    /// <code>
    ///     WSILGenerator generator = new WSILGenerator();
    ///     generator.setFileName("inspection.wsil");
    ///     generator.addWS("http...wsdl", "wsName");
    ///     generator.removeWS("wsName2");
    ///     generator.saveWSIL();
    /// </code>
    /// </example>
    public class WSILGenerator
    {
        private string filename = null;
        private XmlDocument xmlDoc;
        
        static void Main(string[] args)
        {

            WSILGenerator generator = new WSILGenerator();
            //generator.addWS("http...wsdl", "wsName");
            generator.removeWS("wsName");
            generator.saveWSIL();
        }
        public WSILGenerator()
        {
        }

        public WSILGenerator(string filename)
        {
            this.xmlDoc = new XmlDocument();
            setFileName(filename);
        }

        /// <summary>
        /// set path to WSIL file. If it isn't present, it will be created a new one.
        /// Do not forget to call saveWSIL() method! otherwise all changes will be lost.
        /// </summary>
        /// <param name="filename"></param>
        public void setFileName(string filename)
        {
            this.filename = filename;
            try
            {
                this.xmlDoc.Load(filename);
            }
            catch (Exception e)
            {
                //if file is not found, create a new xml file
                XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
                xmlWriter.Formatting = Formatting.Indented;
                xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
                xmlWriter.WriteStartElement("wsil","inspection","http://schemas.xmlsoap.org/ws/2001/10/inspection/");
                xmlWriter.Close();
                xmlDoc.Load(filename);
            }
            
        }

        /// <summary>
        /// Add reference to webservice to the WSIL file. 
        /// </summary>
        /// <param name="URLtoWSDL">URL where is located WSDL file for given webservice</param>
        /// <param name="wsName">webservice's name (will be saved in WSIL at location /inspection/service/name)</param>
        public void addWS(string URLtoWSDL, string wsName)
        {
            
            // section unique for all ws
            XmlNode serviceElement = this.xmlDoc.CreateElement("service");

            XmlElement nameElement = xmlDoc.CreateElement("name");
            nameElement.InnerText = wsName;

            XmlElement descriptionElement = xmlDoc.CreateElement("description");
            descriptionElement.SetAttribute("location", URLtoWSDL);
            descriptionElement.SetAttribute("referencedNamespace", "http://schemas.xmlsoap.org/wsdl/");

            serviceElement.AppendChild(nameElement);
            serviceElement.AppendChild(descriptionElement);
            xmlDoc.DocumentElement.AppendChild(serviceElement);         
        }

        /// <summary>
        /// remove webservice by its name
        /// </summary>
        /// <param name="wsName">webservice's name to be deleted (value will be compared with values of elements //inspection/service/name.</param>
        public void removeWS(string wsName)
        {
            XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable);
            manager.AddNamespace("wsil", "http://schemas.xmlsoap.org/ws/2001/10/inspection/");
            XmlNode node = xmlDoc.SelectSingleNode("/wsil:inspection/wsil:service[wsil:name='wsName']", manager);
            node.ParentNode.RemoveChild(node);
        }


        /// <summary>
        /// save opened WSIL file. This method must be called at the end, otherwise WSIL file won't be saved and data will be lost!
        /// </summary>
        public void saveWSIL()
        {
            this.xmlDoc.Save(this.filename);
        }
    }
}
